package com.xbongbong.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.ConfigConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.pro.enums.errorcodes.InvoiceErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.InvoiceConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.PayRelationshipEnum;
import com.xbongbong.saas.enums.business.PaymentRelationshipEnum;
import com.xbongbong.saas.enums.business.PurchaseInvoiceEnum;
import com.xbongbong.saas.help.SaveFormatHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2021/07/19 11:17
 */
public class InvoiceUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(InvoiceUtil.class);


    /**
     * 检测合并开票的金额
     * @param saasNeedRedundantAttrPojo 关联信息pojo
     * @param amountDetail 金额明细
     * @param data 数据data
     * @param originId 原始发票id
     * @throws XbbException
     */
    public static void verifyUnionInvoiceMoney(SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo, Map<String, Object> relationMap, JSONArray amountDetail, JSONObject data, Long originId, List<Long> contractOrPurchaseIds, List<Long> refIds, Integer businessType) throws XbbException {
        Integer contractNum = (Integer) relationMap.getOrDefault("contractNum",0);
        Integer paymentNum = (Integer) relationMap.getOrDefault("paymentNum",0);
        Integer paymentSheetNum = (Integer) relationMap.getOrDefault("paymentSheetNum",0);
        Integer purchaseNum = (Integer) relationMap.getOrDefault("purchaseNum",0);
        Integer payPlanNum = (Integer) relationMap.getOrDefault("payPlanNum",0);
        Integer paySheetNum = (Integer) relationMap.getOrDefault("paySheetNum",0);
        boolean isRed = false;
        Map<Long,String> contractOrPurchaseMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long,String> paymentOrPayPlanMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long,String> paymentSheetOrPaySheetMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(originId > 0){
            isRed = true;
        }
        getRefIdAndNoMap(saasNeedRedundantAttrPojo,contractOrPurchaseMap,paymentOrPayPlanMap,paymentSheetOrPaySheetMap,data,businessType);
        JSONArray removeArray = new JSONArray();
        if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
            if (saasNeedRedundantAttrPojo.isContractUnion()) {
                commonRemoveIllegalRef(InvoiceEnum.CONTRACT_ID.getAttr(),InvoiceEnum.CONTRACT_ID_LINK_TEXT.getAttr(),data,amountDetail,contractOrPurchaseMap,isRed,removeArray,contractNum,XbbRefTypeEnum.INVOICE.getCode());
            }
            if(saasNeedRedundantAttrPojo.isPaymentUnion()){
                commonRemoveIllegalRef(InvoiceEnum.PAYMENT_ID.getAttr(),InvoiceEnum.PAYMENT_ID_LINK_TEXT.getAttr(),data,amountDetail,paymentOrPayPlanMap,isRed,removeArray,paymentNum,XbbRefTypeEnum.INVOICE.getCode());
            }
            if(saasNeedRedundantAttrPojo.isPayPlanUnion()){
                commonRemoveIllegalRef(InvoiceEnum.PAYMENT_SHEET_ID.getAttr(),InvoiceEnum.PAYMENT_SHEET_ID_LINK_TEXT.getAttr(),data,amountDetail,paymentSheetOrPaySheetMap,isRed,removeArray,paymentSheetNum,XbbRefTypeEnum.INVOICE.getCode());
            }
            if(CollectionsUtil.isNotEmpty(amountDetail) && CollectionsUtil.isNotEmpty(removeArray)) {
                amountDetail.removeAll(removeArray);
            }
            //这里如果两条合同 一个回款计划可能会显示时合同合并开票,预收款回款单不需要验证这个
            if(!saasNeedRedundantAttrPojo.isPrePaymentSheet() && !saasNeedRedundantAttrPojo.isPrePaymentSheetUnion()){
                getEliminateNoRef(amountDetail,data,contractOrPurchaseMap,paymentNum,paymentSheetNum,XbbRefTypeEnum.INVOICE.getCode());
            }
        }
        if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
            if(saasNeedRedundantAttrPojo.isPurchaseUnion()){
                commonRemoveIllegalRef(PurchaseInvoiceEnum.PURCHASE_ID.getAttr(),PurchaseInvoiceEnum.PURCHASE_ID_LINK_TEXT.getAttr(),data,amountDetail,contractOrPurchaseMap,isRed,removeArray,purchaseNum,XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
            }
            if(saasNeedRedundantAttrPojo.isPayPlanUnion()){
                commonRemoveIllegalRef(PurchaseInvoiceEnum.PAY_PLAN_ID.getAttr(),PurchaseInvoiceEnum.PAY_PLAN_ID_LINK_TEXT.getAttr(),data,amountDetail,paymentOrPayPlanMap,isRed,removeArray,payPlanNum,XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
            }
            if(saasNeedRedundantAttrPojo.isPaySheetUnion()){
                commonRemoveIllegalRef(PurchaseInvoiceEnum.PAY_SHEET_ID.getAttr(),PurchaseInvoiceEnum.PAY_SHEET_ID_LINK_TEXT.getAttr(),data,amountDetail,paymentSheetOrPaySheetMap,isRed,removeArray,paySheetNum,XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
            }
            if(CollectionsUtil.isNotEmpty(amountDetail) && CollectionsUtil.isNotEmpty(removeArray)) {
                amountDetail.removeAll(removeArray);
            }
            if(!saasNeedRedundantAttrPojo.isPrePaySheet() && !saasNeedRedundantAttrPojo.isPrePaySheetUnion()){
                getEliminateNoRef(amountDetail,data,contractOrPurchaseMap,payPlanNum,paySheetNum,XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
            }
        }
        onceMoreSetSizeInvoice(saasNeedRedundantAttrPojo,relationMap,data,contractOrPurchaseIds,refIds,businessType);

    }


    public static void getEliminateNoRef(JSONArray amountDetail,JSONObject data,Map<Long,String> contractOrPurchaseMap,Integer paymentOrPayPlanNum,Integer paymentSheetOrPaySheetNum,Integer businessType){
        Map<Long, List<Long>> refIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String attr = null;
        JSONArray refIdArray = new JSONArray();
        JSONArray refNoArray = new JSONArray();
        if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
            refIdArray = data.getJSONArray(InvoiceEnum.CONTRACT_ID.getAttr());
            refNoArray = data.getJSONArray(InvoiceEnum.CONTRACT_ID_LINK_TEXT.getAttr());
        }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
            refIdArray = data.getJSONArray(PurchaseInvoiceEnum.PURCHASE_ID.getAttr());
            refNoArray = data.getJSONArray(PurchaseInvoiceEnum.PURCHASE_ID_LINK_TEXT.getAttr());
        }
        if (paymentOrPayPlanNum > 0) {
            if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())){
                attr = InvoiceConstant.PAYMENT;
            }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                attr = InvoiceConstant.PAYPLAN;
            }
        } else if (paymentSheetOrPaySheetNum > 0) {
            if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())){
                attr = InvoiceConstant.PAYMENTSHEET;
            }
            if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                attr = InvoiceConstant.PAYSHEET;
            }
        } else {
            return;
        }
        if(CollectionsUtil.isNotEmpty(amountDetail)) {
            for (int i = 0; i < amountDetail.size(); i++) {
                JSONObject amountObject = amountDetail.getJSONObject(i);
                JSONObject contractOrPurchaseContractObject = null;
                JSONObject jsonObject = null;
                if(Objects.nonNull(amountObject)){
                    if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())){
                        contractOrPurchaseContractObject = amountObject.getJSONArray(InvoiceConstant.CONTRACT).getJSONObject(BasicConstant.ZERO);
                    }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                        contractOrPurchaseContractObject = amountObject.getJSONArray(InvoiceConstant.PURCHASE).getJSONObject(BasicConstant.ZERO);
                    }
                    JSONArray jsonArray = amountObject.getJSONArray(attr);
                    jsonObject = CollectionsUtil.isEmpty(jsonArray) || jsonArray.size() < BasicConstant.ONE ? null : jsonArray.getJSONObject(BasicConstant.ZERO);
                }
                if(Objects.nonNull(jsonObject)) {
                    if (refIdMap.containsKey(contractOrPurchaseContractObject.getLong(BasicConstant.ID))) {
                        List<Long> idList = refIdMap.get(contractOrPurchaseContractObject.getLong(BasicConstant.ID));
                        idList.add(jsonObject.getLong(BasicConstant.ID));
                    }else {
                        List<Long> idList = new ArrayList<>();
                        idList.add(jsonObject.getLong(BasicConstant.ID));
                        Long contractOrPurchaseContractid = contractOrPurchaseContractObject.getLong(BasicConstant.ID);
                        //采购合同对应的 付款单 付款计划
                        refIdMap.put(contractOrPurchaseContractid,idList);
                    }
                }
            }
            JSONArray contractOrPurchaseContractIdArray = null;
            if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())){
                contractOrPurchaseContractIdArray = data.getJSONArray(InvoiceEnum.CONTRACT_ID.getAttr());
            }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                contractOrPurchaseContractIdArray = data.getJSONArray(PurchaseInvoiceEnum.PURCHASE_ID.getAttr());
            }

            if(CollectionsUtil.isNotEmpty(contractOrPurchaseContractIdArray)) {
                for (int j = 0; j < contractOrPurchaseContractIdArray.size(); j++) {
                    Long id = contractOrPurchaseContractIdArray.getLong(j);
                    if (refIdMap.size() > 0) {
                        if (!refIdMap.containsKey(id)) {
                            refIdArray.remove(String.valueOf(id));
                            refNoArray.remove(contractOrPurchaseMap.get(id));
                            contractOrPurchaseMap.remove(id);
                        }
                    }
                }
            }
            if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())){
                data.put(InvoiceEnum.CONTRACT_ID.getAttr(),refIdArray);
                data.put(InvoiceEnum.CONTRACT_ID_LINK_TEXT.getAttr(),refNoArray);
            }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                data.put(PurchaseInvoiceEnum.PURCHASE_ID.getAttr(),refIdArray);
                data.put(PurchaseInvoiceEnum.PURCHASE_ID_LINK_TEXT.getAttr(),refNoArray);
            }
        }
    }


    public static void onceMoreSetSizeInvoice(SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo,Map<String, Object> relationMap,JSONObject data,List<Long> contractOrPurchaseIds,List<Long> refIds,Integer businessType)throws XbbException{

        JSONArray contractOrPurchaseContractArray = new JSONArray();
        JSONArray paymentOrPayPlanArray = new JSONArray();
        JSONArray paymentSheetOrPaySheetArray = new JSONArray();
        if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())){
            contractOrPurchaseContractArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, InvoiceEnum.CONTRACT_ID.getAttr(), new JSONArray());
            paymentOrPayPlanArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, InvoiceEnum.PAYMENT_ID.getAttr(), new JSONArray());
            paymentSheetOrPaySheetArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data,InvoiceEnum.PAYMENT_SHEET_ID.getAttr(),new JSONArray());
        }
        if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
            contractOrPurchaseContractArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data,PurchaseInvoiceEnum.PURCHASE_ID.getAttr(), new JSONArray());
            paymentOrPayPlanArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data,PurchaseInvoiceEnum.PAY_PLAN_ID.getAttr(), new JSONArray());
            paymentSheetOrPaySheetArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data,PurchaseInvoiceEnum.PAY_SHEET_ID.getAttr(),new JSONArray());
        }
        Integer contractOrPurchaseNum = contractOrPurchaseContractArray.size();
        Integer paymentOrPayPlanNum = paymentOrPayPlanArray.size();
        Integer paymentSheetOrPaySheetNum = paymentSheetOrPaySheetArray.size();

        if(contractOrPurchaseNum > BasicConstant.ZERO){
            if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
                saasNeedRedundantAttrPojo.setHasContract(true);
                saasNeedRedundantAttrPojo.setContractUnion(false);
            }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                saasNeedRedundantAttrPojo.setHasPurchase(true);
                saasNeedRedundantAttrPojo.setPurchaseUnion(false);
            }
            if(contractOrPurchaseNum > BasicConstant.ONE){
                if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
                    saasNeedRedundantAttrPojo.setContractUnion(true);
                }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                    saasNeedRedundantAttrPojo.setPurchaseUnion(true);
                }
            }
        }else {
            if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
                saasNeedRedundantAttrPojo.setHasContract(false);
            }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                saasNeedRedundantAttrPojo.setHasPurchase(false);
            }
        }
        if (paymentOrPayPlanNum > BasicConstant.ZERO) {
            if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
                saasNeedRedundantAttrPojo.setHasPayment(true);
                saasNeedRedundantAttrPojo.setContractUnion(false);
                saasNeedRedundantAttrPojo.setPaymentSheetUnion(false);
            }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                saasNeedRedundantAttrPojo.setHasPayPlan(true);
                saasNeedRedundantAttrPojo.setPurchaseUnion(false);
                saasNeedRedundantAttrPojo.setPaySheetUnion(false);
            }
            if(paymentOrPayPlanNum > BasicConstant.ONE){
                if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
                    saasNeedRedundantAttrPojo.setPaymentUnion(true);
                }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                    saasNeedRedundantAttrPojo.setPaySheetUnion(true);
                }
            }
        } else {
            if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
                saasNeedRedundantAttrPojo.setHasPayment(false);
            }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                saasNeedRedundantAttrPojo.setHasPayPlan(false);
            }
        }
        if (paymentSheetOrPaySheetNum > BasicConstant.ZERO) {
            if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
                saasNeedRedundantAttrPojo.setHasPaymentSheet(true);
                saasNeedRedundantAttrPojo.setContractUnion(false);
                saasNeedRedundantAttrPojo.setPaymentSheetUnion(false);
            }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                saasNeedRedundantAttrPojo.setHasPaySheet(true);
                saasNeedRedundantAttrPojo.setPurchaseUnion(false);
                saasNeedRedundantAttrPojo.setPaySheetUnion(false);
            }
            if(paymentSheetOrPaySheetNum > BasicConstant.ONE){
                if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
                    saasNeedRedundantAttrPojo.setPaymentSheetUnion(true);
                }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                    saasNeedRedundantAttrPojo.setPaySheetUnion(true);
                    if(saasNeedRedundantAttrPojo.isPrePaySheet()){
                        saasNeedRedundantAttrPojo.setPrePaySheetUnion(true);
                    }
                }
            }
        } else {
            if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
                saasNeedRedundantAttrPojo.setHasPaymentSheet(false);
            }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                saasNeedRedundantAttrPojo.setHasPaySheet(false);
            }
        }
        if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())) {
            relationMap.put("contractNum",contractOrPurchaseNum);
            relationMap.put("paymentNum",paymentOrPayPlanNum);
            relationMap.put("paymentSheetNum",paymentSheetOrPaySheetNum);
        }else if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
            relationMap.put("purchaseNum",contractOrPurchaseNum);
            relationMap.put("payPlanNum",paymentOrPayPlanNum);
            relationMap.put("paySheetNum",paymentSheetOrPaySheetNum);
        }
        contractOrPurchaseIds.clear();
        if(CollectionsUtil.isNotEmpty(refIds)){
            refIds.clear();
        }

        if (contractOrPurchaseContractArray.size()>0) {
            contractOrPurchaseIds.addAll(JSONArray.parseArray(contractOrPurchaseContractArray.toJSONString(),Long.class));
        }
        if(paymentOrPayPlanArray.size()>0) {
            refIds.addAll(JSONArray.parseArray(paymentOrPayPlanArray.toJSONString(),Long.class));
        }else if(paymentSheetOrPaySheetArray.size()>0){
            refIds.addAll(JSONArray.parseArray(paymentSheetOrPaySheetArray.toJSONString(),Long.class));
        }
    }

    /**
     * 删除非法的关联
     */
    public static void commonRemoveIllegalRef(String idAttr,String noAttr,JSONObject data,JSONArray amountDetail,Map<Long,String> map,boolean isRed,JSONArray removeArray,Integer num,Integer businessType) throws XbbException{
        JSONArray refIdArray = data.getJSONArray(idAttr);
        JSONArray refNoArray = data.getJSONArray(noAttr);
        if(CollectionsUtil.isNotEmpty(amountDetail)){
            for (int i = 0; i < amountDetail.size(); i++) {
                JSONObject amountDetailObject = amountDetail.getJSONObject(i);
                Double invoiceTotalMoney = amountDetailObject.getDouble(InvoiceConstant.INVOICE_AMOUNT);
                if(invoiceTotalMoney == 0D){
                    //直接添加金额明细
                    if(!removeArray.contains(amountDetailObject)){
                        removeArray.add(amountDetailObject);
                        num--;
                    }
                    //删除data 中的非法规则数
                    if(Objects.equals(XbbRefTypeEnum.INVOICE.getCode(),businessType)){
                        if(Objects.equals(idAttr,InvoiceEnum.CONTRACT_ID.getAttr())){
                            JSONArray contractArray = amountDetailObject.getJSONArray(InvoiceConstant.CONTRACT);
                            JSONObject contractObject = contractArray.getJSONObject(BasicConstant.ZERO);
                            refIdArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(contractObject,BasicConstant.ID,""));
                            refNoArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(contractObject,BasicConstant.NAME,""));
                        }else if(Objects.equals(idAttr,InvoiceEnum.PAYMENT_ID.getAttr())){
                            JSONArray paymentArray = amountDetailObject.getJSONArray(InvoiceConstant.PAYMENT);
                            JSONObject paymentObject = paymentArray.getJSONObject(BasicConstant.ZERO);
                            refIdArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(paymentObject,BasicConstant.ID,""));
                            refNoArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(paymentObject,BasicConstant.NAME,""));
                        }else if(Objects.equals(idAttr,InvoiceEnum.PAYMENT_SHEET_ID.getAttr())){
                            JSONArray paymentSheetArray = amountDetailObject.getJSONArray(InvoiceConstant.PAYMENTSHEET);
                            JSONObject paymentSheetObject = paymentSheetArray.getJSONObject(BasicConstant.ZERO);
                            refIdArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(paymentSheetObject,BasicConstant.ID,""));
                            refNoArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(paymentSheetObject,BasicConstant.NAME,""));
                        }
                    }else if(Objects.equals(XbbRefTypeEnum.PURCHASE_INVOICE.getCode(),businessType)){
                        if(Objects.equals(idAttr,PurchaseInvoiceEnum.PURCHASE_ID.getAttr())){
                            JSONArray purchaseArray = amountDetailObject.getJSONArray(InvoiceConstant.PURCHASE);
                            JSONObject purchaseContractObject = purchaseArray.getJSONObject(BasicConstant.ZERO);
                            refIdArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(purchaseContractObject,BasicConstant.ID,""));
                            refNoArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(purchaseContractObject,BasicConstant.NAME,""));
                        }else if(Objects.equals(idAttr,PurchaseInvoiceEnum.PAY_PLAN_ID.getAttr())){
                            JSONArray payPlanArray = amountDetailObject.getJSONArray(InvoiceConstant.PAYPLAN);
                            JSONObject payPlanObject = payPlanArray.getJSONObject(BasicConstant.ZERO);
                            refIdArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(payPlanObject,BasicConstant.ID,""));
                            refNoArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(payPlanObject,BasicConstant.NAME,""));
                        }else if(Objects.equals(idAttr,PurchaseInvoiceEnum.PAY_SHEET_ID.getAttr())){
                            JSONArray paySheetArray = amountDetailObject.getJSONArray(InvoiceConstant.PAYSHEET);
                            JSONObject paySheetObject = paySheetArray.getJSONObject(BasicConstant.ZERO);
                            refIdArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(paySheetObject,BasicConstant.ID,""));
                            refNoArray.remove(FastJsonHelper.getStringOrDefaultFromFormData(paySheetObject,BasicConstant.NAME,""));
                        }
                    }
                }
                if(!isRed){
                    if(invoiceTotalMoney < 0D){
                        throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_216020);
                    }
                }
            }
        }
        data.put(idAttr,refIdArray);
        data.put(noAttr,refNoArray);
    }
    /**
     * 获取关联id和关联的编号
     * @param saasNeedRedundantAttrPojo
     * @param contractOrPurchaseMap
     * @param paymentOrPayPlanMap
     * @param paymentSheetOrPaySheetMap
     * @param data
     */
    private static void getRefIdAndNoMap(SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo, Map<Long,String> contractOrPurchaseMap, Map<Long,String> paymentOrPayPlanMap, Map<Long,String> paymentSheetOrPaySheetMap, JSONObject data, Integer businessType) {
        if (Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())){
            if (saasNeedRedundantAttrPojo.isHasContract()) {
                SaveFormatHelp.commonGetRefEntity(InvoiceEnum.CONTRACT_ID.getAttr(), InvoiceEnum.CONTRACT_ID_LINK_TEXT.getAttr(), contractOrPurchaseMap, data);
            }
            if (saasNeedRedundantAttrPojo.isHasPayment()) {
                SaveFormatHelp.commonGetRefEntity(InvoiceEnum.PAYMENT_ID.getAttr(), InvoiceEnum.PAYMENT_ID_LINK_TEXT.getAttr(), paymentOrPayPlanMap, data);
            }
            if (saasNeedRedundantAttrPojo.isHasPaymentSheet()) {
                SaveFormatHelp.commonGetRefEntity(InvoiceEnum.PAYMENT_SHEET_ID.getAttr(), InvoiceEnum.PAYMENT_SHEET_ID_LINK_TEXT.getAttr(), paymentSheetOrPaySheetMap, data);
            }
        }
        if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())) {
            if (saasNeedRedundantAttrPojo.isHasPurchase()) {
                SaveFormatHelp.commonGetRefEntity(PurchaseInvoiceEnum.PURCHASE_ID.getAttr(), PurchaseInvoiceEnum.PURCHASE_ID_LINK_TEXT.getAttr(), contractOrPurchaseMap, data);
            }
            if (saasNeedRedundantAttrPojo.isHasPayment()) {
                SaveFormatHelp.commonGetRefEntity(PurchaseInvoiceEnum.PAY_PLAN_ID.getAttr(), PurchaseInvoiceEnum.PAY_PLAN_ID_LINK_TEXT.getAttr(), paymentOrPayPlanMap, data);
            }
            if (saasNeedRedundantAttrPojo.isHasPaymentSheet()) {
                SaveFormatHelp.commonGetRefEntity(PurchaseInvoiceEnum.PAY_SHEET_ID.getAttr(), PurchaseInvoiceEnum.PAY_SHEET_ID_LINK_TEXT.getAttr(), paymentSheetOrPaySheetMap, data);
            }
        }
    }


    public static void checkContractInvoiceAmountHandle(Map<Long,Double> contractOrPurchaseReadyInvoiceMoneyMap,Map<Long,Double> contractOrPurchaseTotalInvoiceMoneyMap,Long contractOrPurchaseId,Double contractOrPurchaseInvoiceMoney) throws XbbException{
        Double contractOrPurchaseReadyInvoiceMoney = contractOrPurchaseReadyInvoiceMoneyMap.getOrDefault(contractOrPurchaseId,0D);
        Double contractaOrPurchaseTotalMoney = contractOrPurchaseTotalInvoiceMoneyMap.getOrDefault(contractOrPurchaseId,0D);
        //合同的总金额- (已开发票各合同的已开金额+这次的已开金额)
/*        if(Arith.sub(contractaOrPurchaseTotalMoney,Arith.add(contractOrPurchaseReadyInvoiceMoney,contractOrPurchaseInvoiceMoney)) < BasicConstant.ZERO){
            throw new XbbException(InvoiceErrorCodeEnum.APT_ERROR_216001);
        }*/
        //精度限制，如果（已经开票金额 + 准备开票金额）- 合同总金额 > 0.0000001 则说明此次开票金额超过了合同的总金额
        if (Arith.sub(Arith.add(contractOrPurchaseReadyInvoiceMoney,contractOrPurchaseInvoiceMoney),contractaOrPurchaseTotalMoney) >= ConfigConstant.amountAccuracy){
            throw new XbbException(InvoiceErrorCodeEnum.APT_ERROR_216001);
        }
    }



    /**
     *
     * @param contractReadyInvoiceMoneyMap 合同已开票map
     * @param contractTotalInvoiceMoneyMap 合同的总金额
     * @param paymentOrSheetReadyInvoiceMoneyMap 付款计划 付款单 已开票 map
     * @param paymentOrSheetTotalInvoiceMoneyMap 付款计划 付款单 总的金额
     * @param contractId
     * @param paymentOrSheetId
     * @param paymentOrSheetInvoiceMoney 这次付款单 付款计划 开票金额
     * @param businessType
     * @param isPrePaymentSheet
     * @param isPreUnion
     * @throws XbbException
     */
    public static void checkPaymentOrSheetInvoiceAmountHandle(Map<Long,Double> contractReadyInvoiceMoneyMap,Map<Long,Double> contractTotalInvoiceMoneyMap,Map<Long,Double> paymentOrSheetReadyInvoiceMoneyMap,Map<Long,Double> paymentOrSheetTotalInvoiceMoneyMap,
                                                       Long contractId,Long paymentOrSheetId,Double paymentOrSheetInvoiceMoney,Integer businessType,String refCode,boolean isPrePaymentSheet,boolean isPreUnion) throws XbbException{
        Double contractReadyInvoiceMoney = contractReadyInvoiceMoneyMap.getOrDefault(contractId,0D);
        Double paymentOrSheetReadyInvoiceMoney = paymentOrSheetReadyInvoiceMoneyMap.getOrDefault(paymentOrSheetId,0D);
        Double contractTotalMoney = contractTotalInvoiceMoneyMap.getOrDefault(contractId,0D);
        Double paymentOrSheetTotalMoney = paymentOrSheetTotalInvoiceMoneyMap.getOrDefault(paymentOrSheetId,0D);
        //合同的总金额- (已开发票各合同的已开金额+这次的已开金额)
        if(!isPrePaymentSheet && !isPreUnion) {
            if (Arith.sub(contractTotalMoney, Arith.add(contractReadyInvoiceMoney, paymentOrSheetInvoiceMoney)) < BasicConstant.ZERO) {
                if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                    throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_217025);
                }else {
                    LOGGER.warn("非预收款回款单,报错回款单的明细，contractId:{},paymentOrSheetId：{},contractReadyInvoiceMoney:{},paymentOrSheetReadyInvoiceMoney:{},contractTotalMoney:{},paymentOrSheetTotalMoney：{}",
                            contractId,paymentOrSheetId,contractReadyInvoiceMoney,paymentOrSheetReadyInvoiceMoney,contractTotalMoney,paymentOrSheetTotalMoney);
                    throw new XbbException(InvoiceErrorCodeEnum.APT_ERROR_216001);
                }
            }
        }
        if(Arith.sub(paymentOrSheetTotalMoney,Arith.add(paymentOrSheetReadyInvoiceMoney,paymentOrSheetInvoiceMoney)) < BasicConstant.ZERO) {
            if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode())) {
                if(Objects.equals(refCode, PayRelationshipEnum.PAY_PLAN.getCode())){
                    throw new XbbException(InvoiceErrorCodeEnum.APT_ERROR_217013);
                } else {
                    throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_217014);
                }
            }else {
                if(Objects.equals(refCode, PaymentRelationshipEnum.PAYMENT.getCode())){
                    throw new XbbException(InvoiceErrorCodeEnum.APT_ERROR_216002);
                }else {
                    LOGGER.warn("预收款回款单,报错回款单的明细，contractId:{},paymentOrSheetId：{},contractReadyInvoiceMoney:{},paymentOrSheetReadyInvoiceMoney:{},contractTotalMoney:{},paymentOrSheetTotalMoney：{}",
                            contractId,paymentOrSheetId,contractReadyInvoiceMoney,paymentOrSheetReadyInvoiceMoney,contractTotalMoney,paymentOrSheetTotalMoney);
                    throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_216022);
                }
            }
        }
    }


}
